/* 
 * %W% %E% Enrique Madrid
 *
 * Copyright (c) 1975-2008 M&T Consulting, Inc. All rights Reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this program; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
*/

package com.myt.tools.obtk.openbravo.account;

import java.util.Scanner;

public class Account {

    public static final String ACC_DSV_DELIMITER = ",";
        
    public enum Type {
	A("Asset"), L("Liability"), O("Owner's equity"), 
	    E("Expensive"), R("Revenue"), M("Memo");
	
	private final String desc;
	
	Type(String d) {
	    this.desc = d;
	}

	public String toString() {
	    String ret = "";
	
	    switch (this) {
	    case A:
		ret = "A";
		break;
	    case L:
		ret = "L";
		break;
	    case O:
		ret = "O";
		break;
	    case E:
		ret = "E";
		break;
	    case R:
		ret = "R";
		break;
	    case M:
		ret = "M";
		break;
	    }

	    return ret;
	}

	public String getDescription() {
	    return desc;
	}
    }

    public enum Sign {
	N("Natural"), D("Debit"), C("Credit"), E("Empty");

	private final String desc;

	Sign (String d) {
	    this.desc = d;
	}

	public String toString() {
	    String ret = "E";
	    switch (this) {
	    case N:
		ret = "N";
		break;
	    case D:
		ret = "D";
		break;
	    case C:
		ret = "C";
		break;

	    }
	    return ret;
	}
    }

    public enum Boolean {
	Y("Yes"), N("No"), E("Empty");

	private final String desc;

	Boolean (String d) {
	    this.desc = d;
	}
	
	public String toString() {
	    String ret = "E";
	    switch (this) {
	    case Y:
		ret = "Y";
		break;
	    case N:
		ret = "N";
		break;
	    }
	    return ret;
	}

	public String getDescription() {
	    return desc;
	}

    }

    public enum Level {
	C("Account"),
	    D("Breakdown"),
	    E("Heading"),
	    S("Subaccount");

	private final String desc;

	Level (String d) {
	    this.desc = d;
	}

	public String toString() {
	    String ret = "";
	    
	    switch (this) {
	    case C:
		ret = "C";
		break;
	    case D:
		ret = "D";
		break;
	    case E:
		ret = "E";
		break;
	    case S:
		ret = "S";
		break;
	    }

	    return ret;
	}

	public String getDescription() {
	    return desc;
	}
    }


    private String value = "";
    private String name = null;
    private String description = "";
    private Account.Type type = Account.Type.A;
    private Account.Sign sign = Account.Sign.E;
    private Account.Boolean isDocument = Account.Boolean.N;
    private Account.Boolean isSummary = Account.Boolean.N;
    private String account = "";
    private String parent = "";
    private Account.Level level = Account.Level.C;
    private String operands = "";

    public static Account newInstance(final String line, final String delimiter) {
	Account ac = new Account();
	int i = 0;
	Scanner sc = new Scanner(line);
	sc.useDelimiter(delimiter);

	while (sc.hasNext()) {
	    switch (i++) {
	    case 0:
		ac.setValue(sc.next());
		break;
	    case 1:
		ac.setName(sc.next());
		break;
	    case 2:
		ac.setDescription(sc.next());
		break;
	    case 3:
		ac.setType(sc.next());
		break;
	    case 4:
		ac.setSign(sc.next());
		break;
	    case 5:
		ac.setIsDocument(sc.next());
		break;
	    case 6:
		ac.setIsSummary(sc.next());
		break;
	    case 7:
		ac.setAccount(sc.next());
		break;
	    case 8:
		ac.setParent(sc.next());
		break;
	    case 9:
		ac.setLevel(sc.next());
		break;
	    case 10:
		ac.setOperands(sc.next());
		break;
	    default:
		break;
	    }
	}

	// Validate account's propeties
	if (ac.toStringName() == null) {
	    ac = null;
	}


	return ac;
    }

    public static Account newInstance(final String line) {
	return newInstance(line, ACC_DSV_DELIMITER);
    }

    public final String toStringValue() {
	return value;
    }

    public final String toStringName() {
	return name;
    }

    public final String toStringDescription() {
	return description;
    }

    public final String toStringType() {	
	return type.toString();
    }

    public final String toStringSign() {
	// It's currently not used in Openbravo ERP.
	return sign.toString();
    }

    public final String toStringIsDocument() {
	return isDocument.toString();
    }

    public final String toStringIsSummary() {
	return isSummary.toString();
    }

    public final String toStringAccount() {
	return account;
    }

    public final String toStringParent() {
	return parent;
    }

    public final String toStringLevel() {
	return level.toString();
    }

    public String toStringOperands() {
	return operands;
    }

    public String toString() {
	String s;
	s = toStringValue() + "," + 
	    toStringName() + "," + 
	    toStringDescription() + "," +
	    toStringType() + "," + 
	    toStringSign() + "," +
	    toStringIsDocument() + "," +
	    toStringIsSummary() + "," +
	    toStringAccount() + "," +
	    toStringParent() + "," +
	    toStringLevel() + "," +
	    toStringOperands();
	return s;
    }

    public void setValue(String v) {
	value = v;
    }

    public void setName(String n) {
	name = n;
    }

    public void setDescription(String d) {
	description = d;
    }

    public void setType(String t) {
	try {
	    this.type = Account.Type.valueOf(t.substring(0,1));
	} catch (Exception e) {
	    this.type = Account.Type.A;
	}
    }

    public void setSign(String s) {
	// It's currently not used in Openbravo ERP.
    }

    public void setIsDocument(String b) {
	try {
	    this.isDocument = Account.Boolean.valueOf(b.substring(0,1));
	} catch (Exception e) {
	    this.isDocument = Account.Boolean.E;
	}
    }

    public void setIsSummary(String b) {
	try {
	    this.isSummary = Account.Boolean.valueOf(b.substring(0,1));
	} catch (Exception e) {
	    this.isSummary = Account.Boolean.E;
	}
    }

    public void setAccount(String a) {
	account = a;
    }
    
    public void setParent(String p) { 
	parent = p;
    }
    
    public void setLevel(String l) {
	try {
	    this.level = Account.Level.valueOf(l.substring(0,1));
	} catch (Exception e) {
	    this.level = Account.Level.C;
	}

    }
    
    public void setOperands(String o) {
	operands = o;
    }

}